﻿using MvvmCross.Core.ViewModels;

namespace Sidvall.UI.Navigation
{
	public class HistoryItemCollection : System.Collections.ObjectModel.Collection<HistoryItem>
	{
		#region Public Members

		#region CanGoBack

		public bool CanGoBack
		{
			get
			{
				return this.CurrentIndex > 0;
			}
		}

		#endregion
		#region CanGoForward

		public bool CanGoForward
		{
			get
			{
				return this.Count > this.CurrentIndex + 1;
			}
		}

		#endregion
		#region CanRefresh

		public bool CanRefresh
		{
			get
			{
				if (this.CurrentItem == null)
					return false;
				return true;
			}
		}

		#endregion
		#region CurrentIndex

		private int _CurrentIndex;
		public int CurrentIndex
		{
			get
			{
				return _CurrentIndex;
			}
			private set
			{
				if (value < 0)
					_CurrentIndex = 0;
				else if (value >= this.Count)
					_CurrentIndex = this.Count - 1;
				else
					_CurrentIndex = value;
			}
		}

		#endregion
		#region CurrentItem

		public HistoryItem CurrentItem
		{
			get
			{
				if (this.Count == 0)
					return null;
				if (this.Count <= this.CurrentIndex)
					return null;
				return this[this.CurrentIndex];
			}
		}

		#endregion
		#region MaxCount

		private int? _MaxCount;
		public int? MaxCount
		{
			get
			{
				return _MaxCount;
			}
			set
			{
				_MaxCount = value;
			}
		}

		#endregion

		#region AddItem

		public bool AddItem(HistoryItem state)
		{
			return AddItem(state, true);
		}
		public bool AddItem(HistoryItem state, bool setAsCurrentItem)
		{
			if (state == null)
				return false;

			if (setAsCurrentItem)
			{
				for (int i = this.Count - 1; i >= this.CurrentIndex + 1; i--)
					RemoveAt(i);
				Add(state);
				this.CurrentIndex = this.Count - 1;
			}
			else
			{
				Add(state);
			}

			return true;
		}
		public bool AddItem(HistoryRegionItem state)
		{
			HistoryItem historyItem;

			if (state == null)
				return false;
			if (string.IsNullOrWhiteSpace(state.RegionName))
				return false;

			if ((this.CurrentItem == null) || (!this.CurrentItem.AddRegionItem(state)))
			{
				historyItem = new HistoryItem();
				if (!historyItem.AddRegionItem(state))
					return false;
				return AddItem(historyItem);
			}

			return true;
		}

		#endregion
		#region InsertItem

		protected override void InsertItem(int index, HistoryItem item)
		{
			base.InsertItem(index, item);

			if (this.MaxCount != null)
			{
				while (this.MaxCount < this.Count)
					RemoveAt(0);
			}
		}

		#endregion
		#region RemoveLastItem

		public bool RemoveLastItem()
		{
			int index;

			index = this.Count - 1;
			if (index < 0)
				return false;
			RemoveAt(index);
			if (this.CurrentIndex > index)
				this.CurrentIndex = index;

			return true;
		}

		#endregion

		#region GoBack

		public bool GoBack()
		{
			string[] regionNames;

			if (!this.CanGoBack)
				return false;

			regionNames = GetRegionNames();
			this.CurrentIndex -= 1;
			ShowViewModels(regionNames);

			return true;
		}

		#endregion
		#region GoForward

		public bool GoForward()
		{
			string[] regionNames;

			if (!this.CanGoForward)
				return false;

			regionNames = GetRegionNames();
			this.CurrentIndex += 1;
			ShowViewModels(regionNames);

			return true;
		}

		#endregion
		#region GoToPosition

		public bool GoToPosition(int index)
		{
			return GoToPosition(index, true);
		}
		public bool GoToPosition(int index, bool showViewModel)
		{
			string[] regionNames;

			if (index < 0)
				return false;
			else if (index >= this.Count)
				return false;
			regionNames = GetRegionNames();
			this.CurrentIndex = index;
			if (showViewModel)
				ShowViewModels(regionNames);

			return true;
		}

		#endregion
		#region Refresh

		public bool Refresh()
		{
			string[] regionNames;

			if (!this.CanRefresh)
				return false;

			regionNames = GetRegionNames();
			ShowViewModels(regionNames);

			return true;
		}

		#endregion

		#endregion
		#region Private Members

		#region GetRegionNames

		private string[] GetRegionNames()
		{
			if (this.CurrentItem == null)
				return null;
			return this.CurrentItem.GetRegionNames();
		}

		#endregion
		#region ShowViewModels

		private void ShowViewModels(string[] regionNames)
		{
			MvxViewModelRequest[] requests;

			if (this.CurrentItem == null)
				return;
			requests = this.CurrentItem.GetViewModelRequests(regionNames);
			Sidvall.UI.ViewModels.PresentationManager.ShowViewModels(requests);
		}

		#endregion

		#endregion
		#region Constructors

		public HistoryItemCollection()
		{
		}

		#endregion
	}
}
